[2025-07-11] CSRF-1, CSRF-2
๐ฆฅ ๋ณธ๋ฌธ
CSRF-1
from flask import Flask, request, render_template
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
import urllib
import os
app = Flask(__name__)
app.secret_key = os.urandom(32)
try:
FLAG = open("./flag.txt", "r").read()
except:
FLAG = "[**FLAG**]"
def read_url(url, cookie={"name": "name", "value": "value"}):
cookie.update({"domain": "127.0.0.1"})
try:
service = Service(executable_path="/chromedriver")
options = webdriver.ChromeOptions()
for _ in [
"headless",
"window-size=1920x1080",
"disable-gpu",
"no-sandbox",
"disable-dev-shm-usage",
]:
options.add_argument(_)
driver = webdriver.Chrome(service=service, options=options)
driver.implicitly_wait(3)
driver.set_page_load_timeout(3)
driver.get("http://127.0.0.1:8000/")
driver.add_cookie(cookie)
driver.get(url)
except Exception as e:
driver.quit()
print(str(e))
# return str(e)
return False
driver.quit()
return True
def check_csrf(param, cookie={"name": "name", "value": "value"}):
url = f"http://127.0.0.1:8000/vuln?param={urllib.parse.quote(param)}"
return read_url(url, cookie)
@app.route("/")
def index():
return render_template("index.html")
@app.route("/vuln")
def vuln():
param = request.args.get("param", "").lower()
xss_filter = ["frame", "script", "on"]
for _ in xss_filter:
param = param.replace(_, "*")
return param
@app.route("/flag", methods=["GET", "POST"])
def flag():
if request.method == "GET":
return render_template("flag.html")
elif request.method == "POST":
param = request.form.get("param", "")
if not check_csrf(param):
return '<script>alert("wrong??");history.go(-1);</script>'
return '<script>alert("good");history.go(-1);</script>'
memo_text = ""
@app.route("/memo")
def memo():
global memo_text
text = request.args.get("memo", None)
if text:
memo_text += text
return render_template("memo.html", memo=memo_text)
@app.route("/admin/notice_flag")
def admin_notice_flag():
global memo_text
if request.remote_addr != "127.0.0.1":
return "Access Denied"
if request.args.get("userid", "") != "admin":
return "Access Denied 2"
memo_text += f"[Notice] flag is {FLAG}\n"
return "Ok"
app.run(host="0.0.0.0", port=8000)
- ์ฝ๋๋ฅผ ๋ณด๋ฉด ์ผ๋จ FLAG๋ admin/notice_flag์์ ์ป์ด์ผ ๊ฒ์ ์ ์ ์๋ ๋ฐ ์ป๊ธฐ ์ํด์๋ ip์ฃผ์๊ฐ 127.0.0.1์ userid๊ฐ admin์ด์ด์ผ ํ๋ค.
- read_url์ด ๋ฌด์จ ์๋ฏธ์ธ ์ง ๋ชฐ๋ผ์ ์ฐพ์ ๋ดค๋๋ฐ ์น๋๋ผ์ด๋ฒ๋ฅผ ์ด์ฉํด์ URL์ ์์ฒญํ๋ ์ฝ๋์๋ค. ์ฆ, ์ด ํจ์๋ฅผ ์ด์ฉํ๋ฉด 127.0.0.1๋ก ์ ์ํ ์ ์์ ๊ฒ์ด๋ค.
- read_url์ ์ด์ฉํ๊ธฐ ์ํด์ check_csrf๋ฅผ ์ฌ์ฉํด์ผ ํ๊ณ check_csrf๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์ flag ๋ฉ์๋๋ฅผ Post ๋ฐฉ์์ผ๋ก ์ ๊ทผํด์ผ ํ๋ค. ์ด ๋ param์ ํตํด userId๋ง ํด๊ฒฐํ๋ฉด ๋ฉ๋ชจ์ FLAG๊ฐ ์ฝ์ ๋์ด FLAG๋ฅผ ์ ์ ์์ ๊ฒ์ด๋ค.
- ์ด ๋ on, frame, script๋ ํํฐ๋ง ๋๋ฏ๋ก ์๋๋ฅผ ์ฌ์ฉํ๋ค.
<img src=/admin/notice_flag?userid=admin>
๋ง์นจ flag ํ์ด์ง๋ post ๋ฐฉ์์ผ๋ก ์ ์ถํ ์ ์๋ ํ์ด์ง๋ผ์
์์ ์ฝ๋๋ฅผ ์ ์ถํ๊ณ ๋ฉ๋ชจ ํ์ด์ง์ ๋ค์ด๊ฐ๋๊น
2. CSRF-2
#!/usr/bin/python3
from flask import Flask, request, render_template, make_response, redirect, url_for
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
import urllib
import os
app = Flask(__name__)
app.secret_key = os.urandom(32)
try:
FLAG = open("./flag.txt", "r").read()
except:
FLAG = "[**FLAG**]"
users = {
'guest': 'guest',
'admin': FLAG
}
session_storage = {}
def read_url(url, cookie={"name": "name", "value": "value"}):
cookie.update({"domain": "127.0.0.1"})
try:
service = Service(executable_path="/chromedriver")
options = webdriver.ChromeOptions()
for _ in [
"headless",
"window-size=1920x1080",
"disable-gpu",
"no-sandbox",
"disable-dev-shm-usage",
]:
options.add_argument(_)
driver = webdriver.Chrome(service=service, options=options)
driver.implicitly_wait(3)
driver.set_page_load_timeout(3)
driver.get("http://127.0.0.1:8000/")
driver.add_cookie(cookie)
driver.get(url)
except Exception as e:
driver.quit()
print(str(e))
# return str(e)
return False
driver.quit()
return True
def check_csrf(param, cookie={"name": "name", "value": "value"}):
url = f"http://127.0.0.1:8000/vuln?param={urllib.parse.quote(param)}"
return read_url(url, cookie)
@app.route("/")
def index():
session_id = request.cookies.get('sessionid', None)
try:
username = session_storage[session_id]
except KeyError:
return render_template('index.html', text='please login')
return render_template('index.html', text=f'Hello {username}, {"flag is " + FLAG if username == "admin" else "you are not an admin"}')
@app.route("/vuln")
def vuln():
param = request.args.get("param", "").lower()
xss_filter = ["frame", "script", "on"]
for _ in xss_filter:
param = param.replace(_, "*")
return param
@app.route("/flag", methods=["GET", "POST"])
def flag():
if request.method == "GET":
return render_template("flag.html")
elif request.method == "POST":
param = request.form.get("param", "")
session_id = os.urandom(16).hex()
session_storage[session_id] = 'admin'
if not check_csrf(param, {"name":"sessionid", "value": session_id}):
return '<script>alert("wrong??");history.go(-1);</script>'
return '<script>alert("good");history.go(-1);</script>'
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'GET':
return render_template('login.html')
elif request.method == 'POST':
username = request.form.get('username')
password = request.form.get('password')
try:
pw = users[username]
except:
return '<script>alert("not found user");history.go(-1);</script>'
if pw == password:
resp = make_response(redirect(url_for('index')) )
session_id = os.urandom(8).hex()
session_storage[session_id] = username
resp.set_cookie('sessionid', session_id)
return resp
return '<script>alert("wrong password");history.go(-1);</script>'
@app.route("/change_password")
def change_password():
pw = request.args.get("pw", "")
session_id = request.cookies.get('sessionid', None)
try:
username = session_storage[session_id]
except KeyError:
return render_template('index.html', text='please login')
users[username] = pw
return 'Done'
app.run(host="0.0.0.0", port=8000)
- ๊ธฐ์กด์ ํ์๋ CSRF-2 ๋ฌธ์ ์ ๋น์ทํ๋ค. ๋ชฉํ๋ admin์ ๋น๋ฐ๋ฒํธ๋ฅผ ๋ณ๊ฒฝํด์ admin์ผ๋ก ๋ก๊ทธ์ธํด์ Flag๋ฅผ ๋ณด๋ ๊ฒ์ด๋ค.
-
login API
๋ก๊ทธ์ธ ์ ๋๋ค ์์ฑ โ ์ธ์ ์คํ ๋ฆฌ์ง์ { ๋๋ค : ์์ด๋} ์ ์ฅ โ ์ฟ ํค {์์ด๋ : ๋๋ค }
-
flag API
param์ ๋ฐ์์ด โ ๋๋ค ์ซ์ ์์ฑ โ ์ธ์ ์คํ ๋ฆฌ์ง์ {๋๋ค : admin } ์ ์ฅ โ check_csrf์ param๊ณผ ๋๋ค ์ซ์๋ฅผ ๋ณด๋
-
๋น๋ฐ๋ฒํธ ๋ณ๊ฒฝ API
๋น๋ฐ๋ฒํธ๋ฅผ ๋ฐ์์ด โ ์ฟ ํค์ ๋๋ค ์ซ์์ ์ธ์ ์คํ ๋ฆฌ์ง ์๋ ๋๋ค ์ซ์๋ฅผ ํตํด ํด๋น ์์ด๋์ ๋น๋ฐ๋ฒํธ๋ฅผ ๋ณ๊ฒฝ
-
ํ์ด
flag์์ Post๋ก ์๋์ ์ฝ๋๋ฅผ ๋ณด๋ด๋ฉด
<img src= /change_password?pw=1234>
flag์์ ์ธ์ ์คํ ๋ฆฌ์ง์ ๋๋ค ์ซ์์ admin์์ ๋ฐ๊ธํ๊ณ ๋๋ค ์ซ์๋ฅผ ์ฟ ํค์ ๋ฃ์ด์ ์์ ์ฝ๋๋ฅผ ๋ณด๋ธ๋ค
vuln์์ ํํฐ๋ง ์ดํ ํด๋น ์ฝ๋๋ฅผ ์ํํ๋ค.
๋น๋ฐ๋ฒํธ๋ฅผ ๋ณ๊ฒฝํ ๋ ๋๋ค ์ซ์๋ฅผ ํตํด admin์ ๋น๋ฐ๋ฒํธ๋ฅผ ๋ณ๊ฒฝํ๊ณ admin์ผ๋ก ๋ก๊ทธ์ธ ํ๋ฉด ํด๊ฒฐ!
Leave a comment